//*************************************************//
//* Double-link list with blackjack and iterators *//
//*************************************************//
//* Warning! Modificated for base, not for use

#ifndef LIST_H
#define LIST_H

#include <iterator>
#include <cstring>

namespace lmf {

class List
{
private:

	struct Node;					// node structure © captain obvious

	Node* head;						// list's head pointer © captain obvious
	Node* tail;

	unsigned int List_size;
	int dat_size;

public:

	typedef char* value_type;			// typedefs needed to be an stl-like container
	typedef char** pointer;
	typedef char*& reference;
	typedef const char*& const_reference;
	typedef const char** const_pointer;

	class iterator;					// iterator class © captain obvious

	List(int,int=0);					// basic constructor © captain obvious
	List(const List&);
	iterator begin();				// returns the iterator, ajusted to the first node (head, exactly)
	iterator end();					// returns the iterator, ajusted to the node which follows the last one
	std::reverse_iterator<iterator> rbegin();		// symethric reverse iterator's ajusters
	std::reverse_iterator<iterator> rend();			// both
	int size();						// returns the actual size of a list
	List& push_back(char*);			// add a new node to the list's end
	List& push_front(char*);			// add a new node to the list's front
	iterator insert(iterator,char*);	// add a new node to the custom place (returns added element's iterator)
	iterator remove(iterator);		// dlete a node from position (returns iterator to the next element)
	~List();						// basic destructor © captain obvious
};

struct List::Node					// it's too obvious even for a captain
{
	char* val;
	int buf_size;
	Node* prev;
	Node* next;

    Node(int s,Node* p=0,Node* n=0) : buf_size(s), prev(p), next(n)
    {
        val=new char[buf_size];
    }
	Node(char* b,int s,Node* p=0,Node* n=0) : buf_size(s), prev(p), next(n)
    {
        val=new char[buf_size];
        memmove(val,b,buf_size);
    }
    Node(const Node& nd) : buf_size(nd.buf_size), prev(nd.prev), next(nd.next)
    {
        val=new char[buf_size];
        memmove(val,nd.val,buf_size);
    }
    Node& operator=(const Node& nd)
    {
        buf_size=nd.buf_size;
        prev=nd.prev;
        next=nd.next;
        memmove(val,nd.val,buf_size);
        return *this;
    }
	~Node() { delete[] val; }
};

class List::iterator : public std::iterator<std::bidirectional_iterator_tag,char*> // and it's not, cause it's a bi-iterator's child
{
protected:
	friend class List;				// userfull
	Node* curr;						// current node's pointer

public:
	iterator() : curr(0) {}			// constructors (thus, undefined iterator is invalid and crushes beind incrimented)
	iterator(Node& nd) : curr(&nd) {}					// rarely used
	iterator(Node* nd) : curr(nd) {}					// userfull
	char*& operator*() const { return curr->val; }		// standard
	char** operator->() const { return &(curr->val); }	// both
	iterator& operator++()			// incrementing operator (both versions available)
	{
		curr=curr->next;
		return *this;
	}
	iterator operator++(int)		// and are not more equivalent
	{
		iterator tmp(curr);
		curr=curr->next;
		return tmp;
	}
	iterator& operator--()			// decrementing operator (both versions available)
	{
		curr=curr->prev;
		return *this;
	}
	iterator operator--(int)		// and are not more equivalent
	{
		iterator tmp(curr);
		curr=curr->prev;
		return tmp;

	}
	bool operator==(const iterator& it) const { return curr==it.curr; }
	bool operator!=(const iterator& it) const { return curr!=it.curr; }
	~iterator() {}
};

}

#endif
